using Beauty.Net.Ocelot.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;

namespace Beauty.Net.Ocelot;

/// <summary>
/// Ocelot服务集合扩展
/// </summary>
public static class OcelotServiceCollectionExtensions
{
    /// <summary>
    /// 添加Ocelot网关服务
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configuration">配置对象</param>
    /// <param name="sectionName">配置节名称</param>
    /// <returns>Ocelot构建器</returns>
    public static Beauty.Net.Ocelot.Core.IOcelotBuilder AddOcelotGateway(
        this IServiceCollection services,
        IConfiguration configuration,
        string sectionName = "Ocelot")
    {
        // 绑定配置
        services.Configure<OcelotOptions>(configuration.GetSection(sectionName));
        
        // 创建Ocelot构建器
        var ocelotBuilder = new Beauty.Net.Ocelot.Core.OcelotBuilder(services);
        
        // 注册配置管理器
        services.AddSingleton<IOcelotConfigurationManager, OcelotConfigurationManager>();
        services.AddSingleton<Beauty.Net.Ocelot.Core.IOcelotBuilder>(ocelotBuilder);
        
        // 获取Ocelot选项
        var options = configuration.GetSection(sectionName).Get<OcelotOptions>() ?? new OcelotOptions();
        
        // 添加Ocelot服务
        services.AddOcelot(configuration);
        
        // Ocelot 23.0.0版本移除了AddConsul和AddConfigStoredInMemory方法
        // 服务发现配置将在UseOcelot时通过ocelot.json配置文件提供
        
        return ocelotBuilder;
    }
    
    /// <summary>
    /// 添加Ocelot网关服务（使用配置委托）
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configureOptions">配置委托</param>
    /// <returns>Ocelot构建器</returns>
    public static Beauty.Net.Ocelot.Core.IOcelotBuilder AddOcelotGateway(
        this IServiceCollection services,
        Action<OcelotOptions> configureOptions)
    {
        // 配置选项
        services.Configure(configureOptions);
        
        // 创建Ocelot构建器
        var ocelotBuilder = new Beauty.Net.Ocelot.Core.OcelotBuilder(services);
        
        // 注册配置管理器
        services.AddSingleton<IOcelotConfigurationManager, OcelotConfigurationManager>();
        services.AddSingleton<Beauty.Net.Ocelot.Core.IOcelotBuilder>(ocelotBuilder);
        
        // 获取Ocelot选项
        var options = new OcelotOptions();
        configureOptions(options);
        
        // 添加Ocelot服务
        services.AddOcelot();
        
        // Ocelot 23.0.0版本移除了AddConsul方法
        // 服务发现配置将在UseOcelot时通过ocelot.json配置文件提供
        
        return ocelotBuilder;
    }
    
    /// <summary>
    /// 配置Ocelot路由
    /// </summary>
    /// <param name="builder">Ocelot构建器</param>
    /// <param name="routes">路由配置列表</param>
    /// <returns>Ocelot构建器</returns>
    public static Beauty.Net.Ocelot.Core.IOcelotBuilder ConfigureRoutes(
        this Beauty.Net.Ocelot.Core.IOcelotBuilder builder,
        List<ApiRouteOptions> routes)
    {
        // 在启动时配置路由
        builder.Services.AddHostedService<ConfigureRoutesHostedService>(sp =>
        {
            var configurationManager = sp.GetRequiredService<IOcelotConfigurationManager>();
            return new ConfigureRoutesHostedService(configurationManager, routes);
        });
        
        return builder;
    }
    
    /// <summary>
    /// 启用Ocelot管理API
    /// </summary>
    /// <param name="builder">Ocelot构建器</param>
    /// <param name="path">管理API路径</param>
    /// <param name="key">管理API密钥</param>
    /// <returns>Ocelot构建器</returns>
    public static Beauty.Net.Ocelot.Core.IOcelotBuilder EnableAdministration(
        this Beauty.Net.Ocelot.Core.IOcelotBuilder builder,
        string path = "/administration",
        string key = "")
    {
        builder.Services.Configure<OcelotOptions>(options =>
        {
            options.EnableAdministration = true;
            options.AdministrationPath = path;
            options.AdministrationKey = key;
        });
        
        return builder;
    }
}

/// <summary>
/// 配置路由的托管服务
/// </summary>
public class ConfigureRoutesHostedService : IHostedService
{
    private readonly IOcelotConfigurationManager _configurationManager;
    private readonly List<ApiRouteOptions> _routes;
    
    /// <summary>
    /// 构造函数
    /// </summary>
    public ConfigureRoutesHostedService(
        IOcelotConfigurationManager configurationManager,
        List<ApiRouteOptions> routes)
    {
        _configurationManager = configurationManager;
        _routes = routes;
    }
    
    /// <summary>
    /// 启动服务
    /// </summary>
    public async Task StartAsync(CancellationToken cancellationToken)
    {
        if (_routes.Any())
        {
            // 从路由选项创建配置
            var configuration = _configurationManager.CreateConfigurationFromOptions(_routes);
            
            // 更新配置
            await _configurationManager.UpdateConfigurationAsync(configuration, cancellationToken);
        }
    }
    
    /// <summary>
    /// 停止服务
    /// </summary>
    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}